﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http;
using System.Web.Security;
using FimetContoDeposito.BLL;
using FimetContoDeposito.BLL.Facades;
using FimetContoDeposito.BLL.Metadata;
using FimetContoDeposito.BLL.Objects;
using FimetContoDeposito.BLL.ResultSets;
using FimetContoDeposito.DAL;
using GrayParrot.Communications.Configuration;
using GrayParrot.Configuration;
using GrayParrot.Core;
using GrayParrot.Core.Json;
using GrayParrot.Web;
using GrayParrot.Web.Controls;
using GrayParrot.Web.Formly;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace FimetContoDeposito.Controllers
{
	public class CustomersController : GridCrudController<FCD_Customer, DTParameters>
	{
        #region Loading Fields...
        [HttpGet]
        public string LoadFields()
        {
            string retValue = null;

            //var m_fields = FormlyHelper.ToFormly<AnagraficaFamiglieMetadata>(typeof(AnagraficaFamiglieMetadata));

            var m_fields = new FormlyFactory()
                   .AddInput("ragioneSociale", "Ragione Sociale", "", "inserisci la ragione sociale", false, true, 0, 0)
                   .AddInput("note", "Note", "", "inserisci le note", false, false, 0, 0)
                   .Create();

            JsonSerializerSettings settings = new JsonSerializerSettings();
            settings.ContractResolver = new NullToEmptyListResolver();
            settings.Converters = new List<JsonConverter> { new Newtonsoft.Json.Converters.StringEnumConverter { CamelCaseText = false } };
            settings.Formatting = Formatting.Indented;
            settings.NullValueHandling = NullValueHandling.Ignore;

            retValue = JsonConvert.SerializeObject(m_fields, settings);

            return retValue;
        }

        [HttpGet]
        public string[] LoadFields(Guid id)
        {
            string[] retValue = new string[2] { string.Empty, string.Empty };

            FCD_Customer obj = null;
            using (CustomersFacade m_dc = CustomersFacade.Create())
            {
                ReturnValue<FCD_Customer> m_objs = m_dc.Get(id);
                if (m_objs.HasValue)
                {
                    obj = m_objs.Value;
                }
            }

            if (obj != null)
            {
                //var m_fields = FormlyHelper.ToFormly<AnagraficaFamiglieMetadata>(typeof(AnagraficaFamiglieMetadata));
                var m_fields = new FormlyFactory()
                                   .AddInput("RagioneSociale", "Ragione Sociale", "", "inserisci la ragione sociale", false, true, 0, 0)
                                   .AddInput("Note", "Note", "", "inserisci le note", false, false, 0, 0)
                                   .Create();

                JsonSerializerSettings settings = new JsonSerializerSettings();
                settings.ContractResolver = new NullToEmptyListResolver();
                settings.Converters = new List<JsonConverter> { 
                    new Newtonsoft.Json.Converters.StringEnumConverter { CamelCaseText = false }
                };

                settings.Formatting = Formatting.Indented;
                settings.NullValueHandling = NullValueHandling.Ignore;

                retValue[0] = JsonConvert.SerializeObject(m_fields, settings);

                retValue[1] = JsonConvert.SerializeObject(obj);
            }
            else
            {
            }

            //
            return retValue;
        }

        [HttpGet]
        public string LoadFieldsNewCustomer()
        {
            string retValue = null;

            //var m_fields = FormlyHelper.ToFormly<AnagraficaFamiglieMetadata>(typeof(AnagraficaFamiglieMetadata));

            var m_fields = new FormlyFactory()
                   .AddInput("nome", "Nome", "", "inserire il nome dell'operatore", false, true, 0, 0)
                   .AddInput("cognome", "Cognome", "", "inserire il cognome dell'operatore", false, true, 0, 0)
                   .AddInput("username", "UserName", "lo username è necessario in fase di login", "inserire lo username", false, true, 0, 0)
                   .AddInput("password", "Password", "", "inserire la password", false, true, 0, 0, TextFieldBehaviors.Password)
                   //.AddInput("passwordQuestion", "Password Domanda Segreta", "Domanda che viene posta per recuperare la password", "inserisci la domanda segreta per il recupero della password", false, true, 0, 0)
                   //.AddInput("passwordAnswer", "Password Risposta Segreta", "Risposta necessaria affinchè si possa recuperare la password", "inserisci la risposta segreta per il recupero della password", false, true, 0, 0)
                   .AddInput("email", "Email", "", "inserire l'email dell'operatore", false, true, 0, 0, TextFieldBehaviors.Email)
                   .AddTextArea("note", "Note", "", "indicare l'azienda di appartenenza", false, false, 3, 10)
                   .Create();

            JsonSerializerSettings settings = new JsonSerializerSettings();
            settings.ContractResolver = new NullToEmptyListResolver();
            settings.Converters = new List<JsonConverter> { new Newtonsoft.Json.Converters.StringEnumConverter { CamelCaseText = false } };
            settings.Formatting = Formatting.Indented;
            settings.NullValueHandling = NullValueHandling.Ignore;

            retValue = JsonConvert.SerializeObject(m_fields, settings);

            return retValue;
        }

        [HttpGet]
        public string LoadFieldsNewCustomerByFimet()
        {
            string retValue = null;

            var m_fields = FormlyHelper.ToFormly<CustomerOperatorMetadata>(typeof(CustomerOperatorMetadata));
            m_fields.Hide("IsApprovato");

            retValue = FormlyHelper.Serialize(m_fields);
            
            return retValue;           
        }

        [HttpGet]
        public string[] LoadFieldsNewCustomerByFimet(Guid id)
        {
            string[] retValue = new string[2] { string.Empty, string.Empty };

            CustomerOperatorBag obj = null;
            using (CustomerOperatorsFacade m_dc = CustomerOperatorsFacade.Create())
            {
                ReturnValue<CustomerOperatorBag> m_objs = m_dc.GetCustomerOperatorBags(id);
                if (m_objs.HasValue)
                {
                    obj = m_objs.Value;
                }
            }

            if (obj != null)
            {
                var m_fields = FormlyHelper.ToFormly<CustomerOperatorMetadata>(typeof(CustomerOperatorMetadata));
                m_fields.Hide("Password");

                retValue[0] = FormlyHelper.Serialize(m_fields);

                retValue[1] = JsonConvert.SerializeObject(obj);
            }
            else
            {
            }

            //
            return retValue;
        }

        [HttpGet]
        public List<NameValue<string, Guid>> LoadNewCustomerOperators()
        {
            List<NameValue<string, Guid>> retValue = null;

            using (CustomerOperatorsFacade m_cf = CustomerOperatorsFacade.Create())
            {
                var objs = m_cf.GetNewOperators();

                if (objs.HasValue)
                {
                    if (objs.Value.Any())
                    {
                        retValue = objs.Value.Select(x => new NameValue<string, Guid>() { name = x.Cognome + ' ' + x.Nome, value = x.Id }).ToList();
                    }
                }
            }

            return retValue;
        }
        #endregion

        public override System.Net.Http.HttpResponseMessage Load(DTParameters data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            using (CustomersFacade m_dc = CustomersFacade.Create())
            {
                ReturnValue<IQueryable<FCD_Customer>> m_objs = m_dc.GetAll();

                DTResult<FCD_Customer> result = DTResult<FCD_Customer>.Empty("Nessun elemento trovato");
                if (m_objs.HasValue)
                {
                    CustomersResultSet m_rs = new CustomersResultSet(data, m_objs.Value);
                    result = m_rs.GetResult();

                    result.data.OrderBy(x => x.RagioneSociale);
                }
                else
                {
                    if (m_objs.HasError)
                    {
                        result.Message.MessageType = MessageTypes.Error;
                        result.Message.Message = m_objs.Error.Message;
                    }
                }

                retValue = Request.CreateResponse(HttpStatusCode.OK, result);
            }

            return retValue;
        }

        public override System.Net.Http.HttpResponseMessage Add(FCD_Customer data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            using (CustomersFacade m_dc = CustomersFacade.Create())
            {
                ReturnValue<bool> result = m_dc.Add(data);

                if (result.HasValue)
                {
                    retValue = Request.CreateResponse(HttpStatusCode.OK, "Inserimento nuovo magazzino eseguito !");
                }
                else
                {
                    retValue = Request.CreateResponse(HttpStatusCode.OK, "Errore nell'inserimento del nuovo magazzino");
                }
            }

            return retValue;
        }

        public override System.Net.Http.HttpResponseMessage Edit(FCD_Customer data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            using (CustomersFacade m_dc = CustomersFacade.Create())
            {
                ReturnValue<bool> result = m_dc.Edit(data);

                if (result.HasValue)
                {
                    retValue = Request.CreateResponse(HttpStatusCode.OK, "Modifica magazzino eseguito !");
                }
                else
                {
                    retValue = Request.CreateResponse(HttpStatusCode.OK, "Errore nella modifica del magazzino");
                }
            }

            return retValue;
        }

        public override HttpResponseMessage Delete(int id)
        {
            throw new NotImplementedException();
        }

        [HttpPost]
        public override System.Net.Http.HttpResponseMessage Delete(JObject data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            dynamic json = data;
            Guid m_id = Guid.Parse(json.id.ToString());

            using (CustomersFacade m_dc = CustomersFacade.Create())
            {
                ReturnValue<FCD_Customer> m_obj = m_dc.Get(m_id, "FCD_AnagraficaArticolis");

                if (m_obj.HasValue)
                {
                    // verifica che il magazzino non sia in uso...
                    if (m_obj.Value.FCD_AnagraficaArticolis.Count() > 1)
                    {
                        retValue = Request.CreateResponse(HttpStatusCode.OK, "Voce già utilizzato da alcuni articoli di magazzino;\nImpossibile cancellare !");
                    }
                    else
                    {
                        // posso cancellare...
                        ReturnValue<bool> result = m_dc.Delete(m_obj.Value);

                        if (result.HasValue)
                        {
                            retValue = Request.CreateResponse(HttpStatusCode.OK, "Cancellazione magazzino effettuata !");
                        }
                        else
                        {
                            retValue = Request.CreateResponse(HttpStatusCode.OK, "Impossibile cancellare il magazzino, in quanto sono presenti movimenti");
                        }
                    }
                }
                else
                {
                    retValue = Request.CreateResponse(HttpStatusCode.OK, "Errore nella selezione del magazzino");
                }
            }

            return retValue;
        }

        [HttpPost]
        public System.Net.Http.HttpResponseMessage NewUserCustomer(JObject data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            dynamic json = data;
            string m_nome = json.nome.ToString();
            string m_cognome = json.cognome.ToString();
            string m_username = json.username.ToString();
            string m_password = json.password.ToString();
            //string m_passwordQuestion = json.passwordQuestion.ToString();
            //string m_passwordAnswer = json.passwordAnswer.ToString();
            string m_email = json.email.ToString();
            string m_note = json.note.ToString();

            try
            {
                MembershipCreateStatus m_status = MembershipCreateStatus.ProviderError;
                MembershipUser m_user = Membership.CreateUser(m_username, m_password, m_email, "noquestions", "nolies", false, out m_status);

                //MembershipUser m_user = Membership.CreateUser(m_username, m_password);
                if ((m_status == MembershipCreateStatus.Success) && (m_user != null))
                {
                    using (CustomerOperatorsFacade m_cof = CustomerOperatorsFacade.Create())
                    {
                        FCD_CustomersOperator m_co = new FCD_CustomersOperator();
                        m_co.Id = Guid.NewGuid();
                        m_co.Nome = m_nome;
                        m_co.Cognome = m_cognome;
                        m_co.Note = m_note;
                        m_co.UserId = (Guid)m_user.ProviderUserKey;
                        m_co.Email = m_email;

                        ReturnValue<bool> m_result = m_cof.Add(m_co);

                        if (m_result.HasValue)
                        {
                            if (m_result.Value)
                            {
                                retValue = Request.CreateResponse(HttpStatusCode.OK, "Inserimento nuovo magazzino eseguito !");

                                // invio mail di alert nuovo operatore registrato...
                                FCDHelpers.InviaMailNuovaRegistrazione(m_username, m_nome, m_cognome, m_note);
                            }
                        }
                        else
                        {
                            if (m_result.HasError)
                            {
                                string m_msg = string.Format("Errore nell'inserimento del nuovo magazzino: {0}", m_result.Error.Message);
                                retValue = Request.CreateResponse(HttpStatusCode.OK, m_msg);
                            }
                        }
                    }
                }
                else
                {
                    string m_msg = string.Format("Errore nell'inserimento del nuovo magazzino: {0}", m_status.ToString());
                    retValue = Request.CreateResponse(HttpStatusCode.OK, m_msg);
                }
            }
            catch (MembershipCreateUserException ex)
            {
                string m_msg = string.Format("Errore nell'inserimento del nuovo magazzino: {0}", ex.Message);
                retValue = Request.CreateResponse(HttpStatusCode.OK, m_msg);
            }

            return retValue;
        }

        [HttpGet]
        public List<NameValue<string, Guid>> CustomersForDDL()
        {
            List<NameValue<string, Guid>> retValue = null;

            using (CustomersFacade m_cf = CustomersFacade.Create())
            {
                ReturnValue<IEnumerable<NameValue<string, Guid>>> result = m_cf.GetAllNameValue();
                if (result.HasValue)
                {
                    retValue = result.Value.ToList();
                }
            }

            return retValue;
        }

        [HttpPost]
        public System.Net.Http.HttpResponseMessage LoadCustomerOperatorBags(DTParameters data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            using (CustomerOperatorsFacade m_dc = CustomerOperatorsFacade.Create())
            {
                ReturnValue<IQueryable<CustomerOperatorBag>> m_objs = m_dc.GetCustomerOperatorBags();

                DTResult<CustomerOperatorBag> result = DTResult<CustomerOperatorBag>.Empty("Nessun elemento trovato");
                if (m_objs.HasValue)
                {
                    CustomerOperatorsBagResultSet m_rs = new CustomerOperatorsBagResultSet(data, m_objs.Value);
                    result = m_rs.GetResult();
                }
                else
                {
                    if (m_objs.HasError)
                    {
                        result.Message.MessageType = MessageTypes.Error;
                        result.Message.Message = m_objs.Error.Message;
                    }
                }

                retValue = Request.CreateResponse(HttpStatusCode.OK, result);
            }

            return retValue;
        }

        [HttpPost]
        public System.Net.Http.HttpResponseMessage EditCustomerOperatorBags(CustomerOperatorBag data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            using (CustomerOperatorsFacade m_dc = CustomerOperatorsFacade.Create())
            {
                ReturnValue<FCD_CustomersOperator> result = m_dc.Get(data.Id);

                if (result.HasValue)
                {
                    MembershipUser m_user = Membership.GetUser(result.Value.UserId);
                    if (m_user != null)
                    {
                        m_user.IsApproved = true;

                        try
                        {
                            Membership.UpdateUser(m_user);

                            result.Value.CustomerId = data.Customer;
                            result.Value.Email = data.Email;
                            ReturnValue<bool> m_result2 = m_dc.Edit(result.Value);

                            if (m_result2.HasValue)
                            {
                                retValue = Request.CreateResponse(HttpStatusCode.OK, "Abilitazione operatore magazzino eseguita !");
                            }
                            else
                            {
                                if (m_result2.HasError)
                                {
                                    string m_msg = string.Format("Errore nella approvazione dell'operatore del magazzino: {0}", m_result2.Error.Message);
                                    retValue = Request.CreateResponse(HttpStatusCode.OK, m_msg);
                                }
                                else
                                {
                                    retValue = Request.CreateResponse(HttpStatusCode.OK, "Errore nella approvazione dell'operatore del magazzino");
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            string m_msg = string.Format("Errore nella approvazione dell'operatore del magazzino: {0}", ex.Message);
                            retValue = Request.CreateResponse(HttpStatusCode.OK, m_msg);
                        }
                    }
                }
                else
                {
                    retValue = Request.CreateResponse(HttpStatusCode.OK, "Errore nella modifica del'operatore del magazzino");
                }
            }

            return retValue;
        }


        [HttpPost]
        public System.Net.Http.HttpResponseMessage DeleteCustomerOperatorBags(CustomerOperatorBag data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            using (CustomerOperatorsFacade m_dc = CustomerOperatorsFacade.Create())
            {
                ReturnValue<CustomerOperatorBag> m_obj = m_dc.GetCustomerOperatorBags(data.Id);

                if (m_obj.HasValue)
                {
                    ReturnValue<FCD_CustomersOperator> m_op = m_dc.Get(m_obj.Value.Id);
                    if (m_op.HasValue)
                    {
                        ReturnValue<bool> result = m_dc.Delete(m_op.Value);

                        if (result.HasValue)
                        {
                            bool m_result = Membership.DeleteUser(m_obj.Value.Username, true);

                            if (m_result)
                            {
                                retValue = Request.CreateResponse(HttpStatusCode.OK, "Cancellazione operatore magazzino effettuata !");
                            }
                            else
                            {
                                retValue = Request.CreateResponse(HttpStatusCode.OK, "Cancellazione Membership operatore magazzino fallita !");
                            }
                        }
                        else
                        {
                            retValue = Request.CreateResponse(HttpStatusCode.OK, "Errore nella cancellazione dell'operatore del magazzino");
                        }
                    }
                    else
                    {
                        retValue = Request.CreateResponse(HttpStatusCode.OK, "Errore nella selezione del magazzino");
                    }
                }
                else
                {
                    retValue = Request.CreateResponse(HttpStatusCode.OK, "Errore nella selezione dell'operatore del magazzino");
                }
            }

            return retValue;
        }

        [HttpPost]
        public System.Net.Http.HttpResponseMessage ConfirmRegistration(JObject data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            dynamic json = data;
            Guid m_id = Guid.Parse(json.id.ToString());

            using (CustomerOperatorsFacade m_cof = CustomerOperatorsFacade.Create())
            {
                ReturnValue<CustomerOperatorBag> m_operator = m_cof.GetCustomerOperatorBags(m_id);
                if (m_operator.HasValue && m_operator.Value != null)
                {
                    ReturnValue<bool> m_result = FCDHelpers.InviaMailConfermaNuovaRegistrazione(m_operator.Value.Username,
                                                              m_operator.Value.Nome, m_operator.Value.Cognome, m_operator.Value.Email);

                    if (m_result.HasValue && m_result.Value)
                    {
                        retValue = Request.CreateResponse(HttpStatusCode.OK, "Invio email Conferma Registrazione !!");
                    }
                    else
                    {
                        retValue = Request.CreateResponse(HttpStatusCode.OK, "Invio email Conferma Registrazione Fallito !!");
                    }
                }
                else
                {
                    if (m_operator.HasError)
                    {
                        retValue = Request.CreateResponse(HttpStatusCode.OK, m_operator.Error.Message);
                    }
                }
            }

            return retValue;
        }

        //private void InviaMailNuovaRegistrazione(string username, string nome, string cognome)
        //{
        //    CommunicationsSettings m_commCfg = null;
        //    ConfigurationManagerHelper pp = new ConfigurationManagerHelper();
        //    m_commCfg = pp.GetCommunicationsSettings();

        //    GrayParrot.Communications.Configuration.EmailSettings m_es = m_commCfg.EmailSettings;

        //    List<string> m_to = m_es.ToAddresses();
        //    List<string> m_cc = m_es.CcAddresses();

        //    string oggetto = "Registrazione nuovo operatore cliente";
        //    string messaggio = string.Format("Nuova registrazione.<br/>Nome:{1}<br/>Cognome:{2}<br/>Username:{0}", username, nome, cognome);

        //    bool esito = new GrayParrot.Communications.Email.Mailing()
        //                     .Send(m_es.From,
        //                           m_to,
        //                           m_cc,
        //                           oggetto,
        //                           messaggio);
        //}

        //private void InviaMailNuovaRegistrazione(string username, string nome, string cognome, string emailTo)
        //{
        //    CommunicationsSettings m_commCfg = null;
        //    ConfigurationManagerHelper pp = new ConfigurationManagerHelper();
        //    m_commCfg = pp.GetCommunicationsSettings();

        //    GrayParrot.Communications.Configuration.EmailSettings m_es = m_commCfg.EmailSettings;

        //    List<string> m_to = new List<string>();
        //    m_to.Add(emailTo);

        //    string oggetto = "Fimet Conto Deposito - Registrazione utente confermata";
        //    string messaggio = string.Format("Nome:{1}<br/>Cognome:{2}<br/>Username:{0}<br/>Registrazione Confermata.", username, nome, cognome);

        //    bool esito = new GrayParrot.Communications.Email.Mailing()
        //                     .Send(m_es.From,
        //                           m_to,
        //                           null,
        //                           oggetto,
        //                           messaggio);
        //}
	}
}
